package ms.unicorn.modellanguage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import ms.unicorn.Element;

import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.IMetamodelType;
import org.eclipse.gmf.runtime.emf.type.core.ISpecializationType;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;

public class ModelLanguage implements IModelLanguage {
	
	private ArrayList<LanguageElement> elements = new ArrayList<LanguageElement>();
	
	private Map<String, Object> caches = new HashMap<String, Object>();
	private String id;
	private String name;
	
	public void registerElementTypes() {
		for(LanguageElement e: elements) {
			IElementType type = e.getElementType();
			if (type instanceof IMetamodelType)
				ElementTypeRegistry.getInstance().register((IMetamodelType) type);
			else
				ElementTypeRegistry.getInstance().register((ISpecializationType)type);
		}
	}
	
	public IElementType getElementType(String typeId) {
		LanguageElement e = getElement(typeId);
		return e != null ? e.getElementType() : null;
	}
	
	@Override
	public Object getCachedObject(String typeName) {
		Object result = caches.get(typeName);
		return result;
	}
	
	@Override
	public void setCachedObject(Object object) {
		if (object != null)
			caches.put(object.getClass().getName(), object);
	}
	
	@Override
	public void configElement(Element element, ConfigureRequest request) {
		IElementType type = request.getTypeToConfigure();
		if (type instanceof HintedSpecializationType) {
			HintedSpecializationType hintType = (HintedSpecializationType) type;
			element.setElementType(type.getId());
			element.setLanguage(hintType.getLanguage().getId());
			LanguageElement langE = hintType.getElement();
			for(ElementAnnotation anno: langE.getAnnotations()) {
				element.getEAnnotations().add(anno.createEAnnotation());
			}
		}
	}
	
	@Override
	public int getElementCount() {
		return elements.size();
	}

	@Override
	public void addElement(LanguageElement element) {
		elements.add(element);
	}

	@Override
	public LanguageElement getElement(int idx) {
		return elements.get(idx);
	}

	@Override
	public LanguageElement getElement(String id) {
		for (LanguageElement e: elements)
			if (e.getId().equalsIgnoreCase(id))
				return e;
		return null;
	}

	@Override
	public void removeElement(String id) {
		for (int i = elements.size() - 1; i >= 0; i--)
			if (elements.get(i).getId().equalsIgnoreCase(id))
				elements.remove(i);
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public void setId(String langId) {
		if (langId != null && langId.length() > 0)
			this.id = langId;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public void setName(String languageName) {
		if (languageName != null && languageName.length() > 0)
			this.name = languageName;
	}

}
